﻿using System;
using System.ComponentModel;
using System.Net;
using System.Net.Mail;
using ElectronicCommerce.Framework.Logging;
using ElectronicCommerce.Framework.Utility.Mail.Enitity;

namespace ElectronicCommerce.Framework.Utility.Mail.Impl.Smtp
{
    /// <summary>
    /// Smtp Mail Sender
    /// </summary>
    public class SmtpMailSender : IMailSender
    {
        private IMailServer server = new SmtpMailServer();

        #region IMail Members

        public event AsynSendCompletedEventHandler SendCompleted;

        public void Send(MailInfo info)
        {
            bool isAsync = (this.SendCompleted != null);

            MailMessage message = new MailMessage();

            #region Build MailMessage

            message.From = new MailAddress(info.From, info.DisplayName);

            if (info.To != null && info.To.Count > 0)
            {
                foreach (var email in info.To)
                {
                    message.To.Add(new MailAddress(email));
                }
            }

            if (info.CC != null && info.CC.Count > 0)
            {
                foreach (var email in info.CC)
                {
                    message.CC.Add(new MailAddress(email));
                }
            }

            if (info.Bcc != null && info.Bcc.Count > 0)
            {
                foreach (var email in info.Bcc)
                {
                    message.Bcc.Add(new MailAddress(email));
                }
            }

            message.IsBodyHtml = info.IsHtml;
            message.Subject = info.Subject;
            message.SubjectEncoding = info.ContextEncode;
            message.Body = info.Body;

            #endregion

            #region Build SmtpClient

            SmtpClient sender = new SmtpClient();
            sender.Host = server.Host;
            sender.Port = server.Port;

            if (server.UserName.IsNotEmpty() && server.Password.IsNotEmpty())
            {
                sender.Credentials = new NetworkCredential(server.UserName, server.Password);
            }

            sender.DeliveryMethod = SmtpDeliveryMethod.Network;
            sender.EnableSsl = server.EnableSsl;

            #endregion

            try
            {
                if (isAsync)
                {
                    sender.SendCompleted += new SendCompletedEventHandler(sender_SendCompleted);

                    sender.SendAsync(message, info);
                }
                else
                {
                    sender.Send(message);
                }
            }
            catch (Exception ex)
            {
#if (DEBUG)
                throw ex;
#endif
                Logger.Log(ex.ToString());
            }
        }

        void sender_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {

            MailInfo emailInfo = e.UserState as MailInfo;

            if (emailInfo == null)
            {
                return;
            }

            if (e.Cancelled)
            {
#if (DEBUG)
                Logger.Log(string.Format("Send canceled for mail with ID [{0}].", emailInfo.ID));
#endif
            }

            if (e.Error != null)
            {
                Logger.Log(string.Format("Error {1} occurred when sending mail id:[{0}] ", emailInfo.ID, e.Error.ToString()));
            }

            else
            {
#if (DEBUG)
                Logger.Log(string.Format("Message [{0}] was sent.", emailInfo.ID));
#endif
            }

            if (this.SendCompleted != null)
            {
                AsynSendCompletedEventArgs args = new AsynSendCompletedEventArgs()
                {
                    ID = emailInfo.ID,
                };
                this.SendCompleted(args);
            }
        }

        #endregion

    }
}
